#include "StdAfx.h"
#include "CallibrationData.h"

using namespace std;

CvRect GetCvRect(int & index, BYTE* callibrationInfo);
CvPoint GetCvPoint(int & index, BYTE* callibrationInfo);

char * CallibrationData::FileName = "callibrationData.dat";

CallibrationData::CallibrationData(void)
{
}

CallibrationData::~CallibrationData(void)
{
}

CallibrationData* CallibrationData::Deserialize()
{
	CallibrationData * callibrationData = new CallibrationData();
	ifstream fin(FileName);
    string line;
	if (getline(fin, line))
	{
		istringstream tokenizer(line);
		string token;
		int i = 0;
		int points[2];
		i = 0;
		while(getline(tokenizer, token, ','))
		{
			istringstream intIss(token);
			intIss >> points[i++];
		}
		callibrationData->SetCenterMarkerPoint(points[0], points[1]);
	}
	if (getline(fin, line))
	{
		istringstream tokenizer(line);
		string token;
		int i = 0;

		int points[2];
		i = 0;
		while(getline(tokenizer, token, ','))
		{
			istringstream intIss(token);
			intIss >> points[i++];
		}
		callibrationData->SetLeftMarkerPoint(points[0], points[1]);
	}
	if (getline(fin, line))
	{
		istringstream tokenizer(line);
		string token;
		int i = 0;

		int points[2];
		i = 0;
		while(getline(tokenizer, token, ','))
		{
			istringstream intIss(token);
			intIss >> points[i++];
		}
		callibrationData->SetRightMarkerPoint(points[0], points[1]);
	}
	if (getline(fin, line))
	{
		istringstream tokenizer(line);
		string token;
		int i = 0;

		int points[2];
		i = 0;
		while(getline(tokenizer, token, ','))
		{
			istringstream intIss(token);
			intIss >> points[i++];
		}
		callibrationData->SetStethMarkerPoint(points[0], points[1]);
	}
	if (getline(fin, line))
	{
		istringstream tokenizer(line);
		string token;
		int i = 0;
		int points[2];
		i = 0;
		while(getline(tokenizer, token, ','))
		{
			istringstream floatIss(token);
			floatIss >> points[i++];
		}
		callibrationData->SetJugularNotchPoint(points[0], points[1]);
	}
	if (getline(fin, line))
	{
		istringstream tokenizer(line);
		string token;
		int i = 0;
		int points[2];
		i = 0;
		while(getline(tokenizer, token, ','))
		{
			istringstream floatIss(token);
			floatIss >> points[i++];
		}
		callibrationData->SetXiphoidProcessPoint(points[0], points[1]);
	}
	if (getline(fin, line))
	{
		istringstream tokenizer(line);
		string token;
		int i = 0;
		int points[2];
		i = 0;
		while(getline(tokenizer, token, ','))
		{
			istringstream floatIss(token);
			floatIss >> points[i++];
		}
		callibrationData->SetLeftCostalMarginPoint(points[0], points[1]);
	}
	if (getline(fin, line))
	{
		istringstream tokenizer(line);
		string token;
		int i = 0;
		int points[2];
		i = 0;
		while(getline(tokenizer, token, ','))
		{
			istringstream floatIss(token);
			floatIss >> points[i++];
		}
		callibrationData->SetRightCostalMarginPoint(points[0], points[1]);
	}
	return callibrationData;
}

CallibrationData* CallibrationData::ReadAndSaveCallibrationData(IplImage* imageSentForCallibration, BYTE* callibrationInfo)
{
	int index = 0;
	CallibrationData* calibData = new CallibrationData();
	
	CvRect centerMarkerBorder = GetCvRect(index, callibrationInfo);
	CvPoint centerMarkerPointFound = cvPoint(centerMarkerBorder.x + centerMarkerBorder.width / 2, centerMarkerBorder.y + centerMarkerBorder.height / 2);
	calibData->SetCenterMarkerPoint(centerMarkerPointFound.x, centerMarkerPointFound.y);
	SupportiveFunctions::SaveImageRegion(imageSentForCallibration, 
		centerMarkerBorder,
		SupportiveFunctions::CenterMarkerFile);
	
	CvRect leftMarkerBorder = GetCvRect(index, callibrationInfo);
	CvPoint leftMarkerPointFound  = cvPoint(leftMarkerBorder.x + leftMarkerBorder.width / 2, leftMarkerBorder.y + leftMarkerBorder.height / 2);
	calibData->SetLeftMarkerPoint(leftMarkerPointFound.x, leftMarkerPointFound.y);
	SupportiveFunctions::SaveImageRegion(imageSentForCallibration, 
		leftMarkerBorder,
		SupportiveFunctions::LeftMarkerFile);
	
	CvRect rightMarkerBorder = GetCvRect(index, callibrationInfo);
	CvPoint rightMarkerPointFound  = cvPoint(rightMarkerBorder.x + rightMarkerBorder.width / 2, rightMarkerBorder.y + rightMarkerBorder.height / 2);
	calibData->SetRightMarkerPoint(rightMarkerPointFound.x, rightMarkerPointFound.y);
	SupportiveFunctions::SaveImageRegion(imageSentForCallibration, 
		rightMarkerBorder,
		SupportiveFunctions::RightMarkerFile);
	
	CvRect stethMarkerBorder = GetCvRect(index, callibrationInfo);
	calibData->SetStethMarkerPoint(stethMarkerBorder.x + stethMarkerBorder.width / 2, stethMarkerBorder.y + stethMarkerBorder.height / 2);
	SupportiveFunctions::SaveImageRegion(imageSentForCallibration, 
		stethMarkerBorder,
		SupportiveFunctions::StethMarkerFile);

	CvPoint jugularNotchPointFound  = GetCvPoint(index, callibrationInfo);
	CvPoint xiphoidProcessPointFound  = GetCvPoint(index, callibrationInfo);
	CvPoint leftCostalMarginPointFound  = GetCvPoint(index, callibrationInfo);
	CvPoint rightCostalMarginPointFound  = GetCvPoint(index, callibrationInfo);

	calibData->SetJugularNotchPoint(jugularNotchPointFound.x, jugularNotchPointFound.y);
	calibData->SetXiphoidProcessPoint(xiphoidProcessPointFound.x, xiphoidProcessPointFound.y);
	calibData->SetLeftCostalMarginPoint(leftCostalMarginPointFound.x, leftCostalMarginPointFound.y);
	calibData->SetRightCostalMarginPoint(rightCostalMarginPointFound.x, rightCostalMarginPointFound.y);

	//save data model
	calibData->Serialize();
	return calibData;
}
void CallibrationData::Copy(CallibrationData *calibData)
{
	centerMarkerPoint = cvPoint(calibData->GetCenterMarkerPoint().x, calibData->GetCenterMarkerPoint().y);
	leftMarkerPoint = cvPoint(calibData->GetLeftMarkerPoint().x, calibData->GetLeftMarkerPoint().y);
	rightMarkerPoint = cvPoint(calibData->GetRightMarkerPoint().x, calibData->GetRightMarkerPoint().y);
	stethMarkerPoint = cvPoint(calibData->GetStethMarkerPoint().x, calibData->GetStethMarkerPoint().y);

	jugularNotchPoint = cvPoint(calibData->GetJugularNotchPoint().x, calibData->GetJugularNotchPoint().y);
	xiphoidProcessPoint = cvPoint(calibData->GetXiphoidProcessPoint().x, calibData->GetXiphoidProcessPoint().y);
	leftCostalMarginPoint = cvPoint(calibData->GetLeftCostalMarginPoint().x, calibData->GetLeftCostalMarginPoint().y);
	rightCostalMarginPoint = cvPoint(calibData->GetRightCostalMarginPoint().x, calibData->GetRightCostalMarginPoint().y);
}
void CallibrationData::Serialize()
{
	ofstream callibrationFile;
	callibrationFile.open(FileName);
	callibrationFile<<centerMarkerPoint.x<<","<<centerMarkerPoint.y<<endl;
	callibrationFile<<leftMarkerPoint.x<<","<<leftMarkerPoint.y<<endl;
	callibrationFile<<rightMarkerPoint.x<<","<<rightMarkerPoint.y<<endl;
	callibrationFile<<stethMarkerPoint.x<<","<<stethMarkerPoint.y<<endl;

	callibrationFile<<jugularNotchPoint.x<<","<<jugularNotchPoint.y<<endl;
	callibrationFile<<xiphoidProcessPoint.x<<","<<xiphoidProcessPoint.y<<endl;
	callibrationFile<<leftCostalMarginPoint.x<<","<<leftCostalMarginPoint.y<<endl;
	callibrationFile<<rightCostalMarginPoint.x<<","<<rightCostalMarginPoint.y<<endl;
	callibrationFile.close();
}


CvRect GetCvRect(int & index, BYTE* callibrationInfo)
{
	int rectParams[4];
	for (int i = 0; i < 4; i++)
	{
		int intValue = 0;
		intValue = (intValue << 8) + callibrationInfo[index];
		intValue = (intValue << 8) + callibrationInfo[index + 1];
		intValue = (intValue << 8) + callibrationInfo[index + 2];
		intValue = (intValue << 8) + callibrationInfo[index + 3];
		index += 4;
		rectParams[i] = intValue;
	}
	return cvRect(rectParams[0], rectParams[1], rectParams[2], rectParams[3]);
}

CvPoint GetCvPoint(int & index, BYTE* callibrationInfo)
{
	int pointParams[2];
	for (int i = 0; i < 2; i++)
	{
		int intValue = 0;
		intValue = (intValue << 8) + callibrationInfo[index];
		intValue = (intValue << 8) + callibrationInfo[index + 1];
		intValue = (intValue << 8) + callibrationInfo[index + 2];
		intValue = (intValue << 8) + callibrationInfo[index + 3];
		index += 4;
		pointParams[i] = intValue;
	}
	return cvPoint(pointParams[0], pointParams[1]);
}